#include "compress.h"

void Compress::quantize(double **tab, int width, int height,int w)
{
    for(int i=0; i<height; ++i)
    {
        for(int j=0; j<width; ++j)
        {
            //if(j>width/2)
            //{
            tab[i][j]>=0 ? tab[i][j]=std::floor(tab[i][j]/(q*w)) : tab[i][j]=std::ceil(tab[i][j]/(q*w));
            //}
            //tab[i][j]>=0 ? tab[i][j]=std::floor(tab[i][j]/(q*2)) : tab[i][j]=std::ceil(tab[i][j]/(q*2));wrzuconego
            //tab[i][j]=std::floor(tab[i][j]/(q*w));
        }
    }
}

DecompressData* Compress::startCompress(Image *image,int wave)
{
    std::cout<<"start compress"<<std::endl;

    double** transformTabY;
    transformTabY=wavv->transform(image->getYTable(),image->getWidth(),image->getHeight());
    quantize(transformTabY,image->getWidth(),image->getHeight(),1);

    double** transformTabCb;
    transformTabCb=wavv->transform(image->getCbTable(),image->getWidth(),image->getHeight());
    quantize(transformTabCb,image->getWidth(),image->getHeight(),2.5);

    double** transformTabCr;
    transformTabCr=wavv->transform(image->getCrTable(),image->getWidth(),image->getHeight());
    quantize(transformTabCr,image->getWidth(),image->getHeight(),2.5);


    DecompressData* data= new DecompressData(image->getWidth(),image->getHeight());


    data->setY(transformTabY);
    data->setCb(transformTabCb);
    data->setCr(transformTabCr);


    huffmanCode(data,512,512,"compress.bin",wave);

    /*
    for(int i=0; i<image->getHeight(); ++i)
    {
        delete [] transformTabY[i];
        delete [] transformTabCb[i];
        delete [] transformTabCr[i];
    }

    delete[] transformTabY;
    delete[] transformTabCb;
    delete[] transformTabCr;*/


    return data;
}

void Compress::huffmanCode(DecompressData* data, int width, int height, std::string file,int wave)
{
    std::map<int,double> frequency;

    std::vector<double> Y;
    std::vector<double> Cb;
    std::vector<double> Cr;

    //int count=0;
    //int rle=64;

    for(int i=0; i<height; ++i)
    {
        for(int j=0; j<width; ++j)
        {
           /* if(data->getY()[i][j]==0)
            {
                count++;
                if(count == rle)
                {
                    Y.push_back(10000);
                    count=0;
                }
            }else
            {

                for(int l=0; l<count; ++l)
                {
                    Y.push_back(0);
                }*/
                Y.push_back(data->getY()[i][j]);
                Cb.push_back(data->getCb()[i][j]);
                Cr.push_back(data->getCr()[i][j]);
                //count=0;
            //}
        }
    }

/*
    for(int i=0; i<height; ++i)
    {
        for(int j=0; j<width; ++j)
        {
            if(data->getCb()[i][j]==0)
            {
                count++;
                if(count == rle)
                {
                    Cb.push_back(10000);
                    count=0;
                }
            }else
            {
                Cb.push_back(data->getCb()[i][j]);
                count=0;
            }
        }
    }



    for(int i=0; i<height; ++i)
    {
        for(int j=0; j<width; ++j)
        {
            if(data->getCr()[i][j]==0)
            {
                count++;
                if(count == rle)
                {
                    Cr.push_back(10000);
                    count=0;
                }
            }else
            {
                Cr.push_back(data->getCr()[i][j]);http://www.eporner.com/
                count=0;
            }
        }
    }*/

    std::map<int,double> ::iterator it;





    for(int i=-14000; i<14000 ;++i)
    {
        if(std::abs(i)>100)
        {
            frequency[i]=1;
        }
        if(std::abs(i)>50&&std::abs(i)<=100)
        {
            frequency[i]=5;
        }
        if(std::abs(i)>30&&std::abs(i)<=50)
        {
            frequency[i]=15;
        }
        if(std::abs(i)>30&&std::abs(i)<=50)
        {
            frequency[i]=15;
        }
        if(std::abs(i)>4&&std::abs(i)<=30)
        {
            frequency[i]=50;
        }

    }


//   frequency[10000]=43929;
   frequency[0]=740889;
   frequency[-1]=11409;
   frequency[1]= 11964;
   frequency[-4]= 1189;
   frequency[-3]=2017;
   frequency[-2]= 4055;
   frequency[2]= 4293;
   frequency[3]= 2089;
   frequency[4]= 1266;


    for(it=frequency.begin(); it!=frequency.end();++it)
    {
        //std::cout<<(*it).first<<" "<<(*it).second<<std::endl;
        double tmp=(*it).second/(width*height);
        frequency[(*it).first]=tmp;
    }

    //std::cout<<"Fsize "<<frequency.size()<<std::endl;

    Hufftree<int, double> hufftree(frequency.begin(), frequency.end());

    std::vector<bool> hcode;


    std::vector<bool> tmp=hufftree.encode(wave);
    for(unsigned int i=0; i<tmp.size(); ++i)
    {
        hcode.push_back(tmp[i]);
    }


    for(unsigned int j=0; j<Y.size(); ++j)
    {
        std::vector<bool> vec=hufftree.encode(Y[j]);
        for(unsigned int i=0; i<vec.size(); ++i)
        {
            hcode.push_back(vec[i]);
        }
    }


    for(unsigned int j=0; j<Cb.size(); ++j)
    {
        std::vector<bool> vec=hufftree.encode(Cb[j]);
        for(unsigned int i=0; i<vec.size(); ++i)
        {
            hcode.push_back(vec[i]);
        }
    }



    for(unsigned int j=0; j<Cr.size(); ++j)
    {
        std::vector<bool> vec=hufftree.encode(Cr[j]);
        for(unsigned int i=0; i<vec.size(); ++i)
        {
            hcode.push_back(vec[i]);
        }
    }


    saveBits(hcode,file);
}







